<?php

class Public_OpenIdLoginAction extends BlogPublicBaseAction
{
    /**
     * Process HTTP POST request: first stage of OpendID authentication
     * process.
     *
     * @param AgaviRequestDataHolder $rd
     * @return mixed
     */
    public function executeWrite(AgaviRequestDataHolder $rd)
    {
        require_once 'Auth/OpenID/Consumer.php';
        // $user = $this->getContext()->getUser();
        $params = $rd->getParameters();
        $vm = $this->container->getValidationManager();
        $ro = $this->getContext()->getRouting();
        
        $openid = $params['openid'];
        $this->setLoginNameCookie($openid);
        try {
            $consumer = $this->getConsumer();
        } catch (WereWordException $e) {
            $vm->setError('general', $e->getMessage());
            return 'Error';
        }
        $auth_request = $consumer->begin($openid);
        
        if ($auth_request === null) {
            $vm->setError('general', 'Authentication request failed.');
            return 'Error';
        }
        
        /*
        $sreg_request = Auth_OpenID_SRegRequest::build(
            // Required
            array('nickname'),
            // Optional
            array('fullname', 'email'));
            
        if ($sreg_request) {
            $auth_request->addExtension($sreg_request);
        }
        */
        // Redirect the user to the OpenID server for authentication.
        // Store the token for this authentication so we can verify the
        // response.
    
        // For OpenID 1, send a redirect.  For OpenID 2, use a Javascript
        // form to send a POST request to the server.
        
        $return_to = $ro->gen('openid_login', array(), array('relative'=>false));
        if ($auth_request->shouldSendRedirect()) {
            $redirect_url = $auth_request->redirectURL(self::getTrustRoot(),
                                                       $return_to);
    
            // If the redirect URL can't be built, display an error
            // message.
            $this->setAttribute('openid_redirect', $redirect_url);
            /*
            if (Auth_OpenID::isFailure($redirect_url)) {
                displayError("Could not redirect to server: " . $redirect_url->message);
            } else {
                // Send redirect.
                header("Location: ".$redirect_url);
            }
			*/
        } else {
            // Generate form markup and render it.
            $form_id = 'openid_message';
            $form_html = $auth_request->htmlMarkup(self::getTrustRoot(), $return_to,
                                                   false, array('id' => $form_id));
    
            // Display an error if the form markup couldn't be generated;
            // otherwise, render the HTML.
            if (Auth_OpenID::isFailure($form_html)) {
                $vm->setError('general', $form_html->message);
                return 'Error';
            } else {
                $this->setAttribute('openid_html', $form_html);
            }
        }
        
        return 'Success';
    }
    
    public function handleError(AgaviRequestDataHolder $rd)
    {
        $params = $rd->getParameters();
        $this->setLoginNameCookie($params['openid']);
        
        return 'Error';
    }
    
    /**
     * Process HTTP GET request: the second part of OpenID authentication
     * process.
     *
     * @param AgaviRequestDataHolder $rd
     * @return mixed
     */
    public function executeRead(AgaviRequestDataHolder $rd)
    {
        $params = $rd->getParameters();
        $ro = $this->getContext()->getRouting();
        $vm = $this->container->getValidationManager();
        
        try {
            $consumer = $this->getConsumer();
        } catch (WereWordException $e) {
            $vm->setError('general', $e->getMessage());
            return 'Error';
        }
        $return_to = $ro->gen('openid_login', array(), array('relative'=>false));
        $response = $consumer->complete($return_to);
        
        if ($response->status == Auth_OpenID_CANCEL) {
            $vm->setError('general', 'Verification cancelled');
            return 'Error';
        } elseif ($response->status == Auth_OpenID_FAILURE) {
            $vm->setError('general', 'OpenID authentication failed: ' . $response->message);
            return 'Error';
        } else if ($response->status == Auth_OpenID_SUCCESS) {
            require_once 'Auth/OpenID/SReg.php';
            $openid = $response->getDisplayIdentifier();
            $this->setAttribute('openid_login_success', 1);
            //$sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
            //$sreg = $sreg_resp->contents();
            
            $is_new_user = $this->getContext()->getUser()->openIdLogin($openid);
            if ($is_new_user) {
                $this->setAttribute('openid_redirect', $ro->gen('own_profile.view').'?welcome=1');
            } else {
                $this->setAttribute('openid_redirect', $ro->gen('root'));
            }
            return 'Success';
        }
    }
    
	/**
	 * Returns the default view if the action does not serve the request
	 * method used.
	 *
	 * @return     mixed <ul>
	 *                     <li>A string containing the view name associated
	 *                     with this action; or</li>
	 *                     <li>An array with two indices: the parent module
	 *                     of the view to be executed and the view to be
	 *                     executed.</li>
	 *                   </ul>
	 */
	public function getDefaultViewName()
	{
		return 'Error';
	}
	
	protected function getConsumer()
	{
	    require_once 'Auth/OpenID/FileStore.php';
        require_once 'Auth/OpenID/Consumer.php';
	    
	    $store_dir = AgaviConfig::get('wereword.openid_store_dir');
	    if (is_null($store_dir)) {
	        throw new WereWordException('wereword.openid_store_dir config option is not set!');
	    }
	    
	    if (!isset($this->store)) {
    	    if (!file_exists($store_dir) && !mkdir($store_dir)) {
    	        return null;
    	    }
	        $this->store = new Auth_OpenID_FileStore($store_dir);
	    }
	    
	    if (!isset($this->consumer)) {
	        $this->consumer = new Auth_OpenID_Consumer($this->store);
	    }
	    return $this->consumer;
	}
    
    protected static function getTrustRoot() {
        return sprintf("%s://%s:%s%s",
                       self::getScheme(), $_SERVER['SERVER_NAME'],
                       $_SERVER['SERVER_PORT'],
                       dirname($_SERVER['PHP_SELF']));
    }
    
    protected function getScheme() {
        $scheme = 'http';
        if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
            $scheme .= 's';
        }
        return $scheme;
    }
        
	protected function setLoginNameCookie($username)
	{
        $ro = $this->getContext()->getRouting();
        /* @var $response AgaviWebResponse */
        $response = $this->getContext()->getController()->getGlobalResponse();
        $response->setCookie('login_openid', $username, 60*60*24*365, $ro->gen('root'));
	}
    
}

?>